#!usr/bin/env python  
# -*- coding:utf-8 _*-
""" 
@author:robot
@file: v2dataflows.py 
@version:
@time: 2022/03/14 
"""
from TapClientCore.T01_init_conf.v2_init.init_config import timeout_config
from TapException.TM import *
from TapClientCore.T02_tm_api.v2_api.v2_tm import v2tm as TM
from TapClientCore.T03_api_body_templates.v2_api_body import DATAFLOW_CREATE
from TapUtil.decorator.some_useful import timeout
from TapUtil.logfunc.logger import logger


class V2TMFDataFlow:

    @staticmethod
    def _send_dataflow_payload(payload):
        return TM.post_dataflows(payload).get('data')

    @staticmethod
    def _build_dataflow_payload(conf):
        tmp = DATAFLOW_CREATE.copy()
        tmp.update(conf)
        return tmp

    def create_dataflow(self, conf):
        payload = self._build_dataflow_payload(conf)
        return self._send_dataflow_payload(payload)

    @staticmethod
    def dataflow_check_name_repeat(dataflow_name):
        filter = {
            'where': {'name': dataflow_name},
            'fields': {'name': 1},
            'limit': 1
        }
        response = TM.get_dataflows_by_filter(filter)
        if response.get('data').get('total') == 1:
            return True
        return False

    @staticmethod
    def query_dataflow_by_name(dataflow_name):
        filter = {
            "where": {"name": dataflow_name},
            "fields":
                {
                    "id": True,
                    "name": True,
                    "status": True,
                    # "stages": True,
                    "stats": True,
                    # "setting": True
                }
        }
        response = TM.get_dataflows_by_filter(filter)
        data = response.get('data').get('items')[0]
        if data:
            return data
        raise DataFlowNotFound

    @staticmethod
    def operate_dataflow_by_id(operate, dataflow_id):
        """
        {status: "scheduled", id: "622b31c784946174b923a2c6"}
        {status: "stopping", id: "622b310584946174b923a227"}
        :param operate:
        :param dataflow_id:
        :return:
        """
        if operate == 'start':
            payload = {'status': "scheduled", "id": dataflow_id}
            TM.patch_dataflows(payload)
        elif operate == 'stop':
            payload = {'status': "stopping", "id": dataflow_id}
            TM.patch_dataflows(payload)
        elif operate == 'delete':
            where = {"id": {"inq": [dataflow_id]}}
            TM.post_dataflows_remove_all(where)
        else:
            raise DataFlowUpdateError

    def _operate_dataflow_by_name(self, operate, dataflow_name):
        query_result = self.query_dataflow_by_name(dataflow_name)
        self.operate_dataflow_by_id(operate, query_result.get('id'))

    # manage dataflow status

    def manage_delete_dataflow(self, dataflow_name):
        self._operate_dataflow_by_name('delete', dataflow_name)

    def manage_start_dataflow(self, dataflow_name):
        self._operate_dataflow_by_name('start', dataflow_name)

    def manage_stop_dataflow(self, dataflow_name):
        self._operate_dataflow_by_name('stop', dataflow_name)

    @timeout('running', timeout_config)
    def manage_wait_dataflow_to_running(self, dataflow_name):
        query_result = self.query_dataflow_by_name(dataflow_name)
        if query_result.get('status') == 'error':
            raise DataFlowError
        return query_result.get('status')

    @timeout('paused', timeout_config)
    def manage_wait_dataflow_to_stop(self, dataflow_name):
        query_result = self.query_dataflow_by_name(dataflow_name)
        if query_result.get('status') == 'error':
            raise DataFlowError
        return query_result.get('status')

    def manage_stop_and_wait_stop(self, dataflow_name):
        self.manage_stop_dataflow(dataflow_name)
        self.manage_wait_dataflow_to_stop(dataflow_name)

    def manage_start_and_wait_running(self, dataflow_name):
        self.manage_start_dataflow(dataflow_name)
        self.manage_wait_dataflow_to_running(dataflow_name)

    def manage_start_and_wait_stop(self, dataflow_name):
        self.manage_start_dataflow(dataflow_name)
        self.manage_wait_dataflow_to_stop(dataflow_name)
